package com.atguigu.gmall.order.handler.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.common.auth.UserAuthInfo;
import com.atguigu.gmall.common.utils.UserAuthUtils;
import com.atguigu.gmall.enums.OrderStatus;
import com.atguigu.gmall.enums.ProcessStatus;
import com.atguigu.gmall.feign.cart.CartFeignClient;
import com.atguigu.gmall.order.handler.AbstractOrderHandler;
import com.atguigu.gmall.order.dto.DetailDto;
import com.atguigu.gmall.order.dto.OrderSubmitDto;
import com.atguigu.gmall.order.entity.OrderDetail;
import com.atguigu.gmall.order.entity.OrderInfo;
import com.atguigu.gmall.order.entity.OrderStatusLog;
import com.atguigu.gmall.order.mapper.OrderInfoMapper;
import com.atguigu.gmall.order.mapper.OrderStatusLogMapper;
import com.atguigu.gmall.order.service.OrderDetailService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@Slf4j
public class SaveOrderHandler extends AbstractOrderHandler {

    @Autowired
    private CartFeignClient cartFeignClient ;

    @Autowired
    private OrderStatusLogMapper orderStatusLogMapper ;

    @Autowired
    private OrderDetailService orderDetailService ;

    @Autowired
    private OrderInfoMapper orderInfoMapper ;

    @Autowired
    private RabbitTemplate rabbitTemplate ;

    @Override
    public int sort() {
        return 4;
    }

    @Override
    public String process(OrderSubmitDto orderSubmitDto, String tradeNo) {

        // 把提交过来的相关数据保存到对应的数据库
        OrderInfo orderInfo = saveOrderInfo(orderSubmitDto , tradeNo) ;

        // 保存明细数据
        saveOrderDetail(orderInfo , orderSubmitDto) ;

        // 保存订单的状态的日志数据
        saveOrderStatusLog(orderInfo) ;

        // 删除购物车中选中的购物项数据
        cartFeignClient.deleteCheckedCart() ;

        // 发布一个延迟任务
//        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(8);
//        scheduledThreadPool.schedule(() -> closeOrder(orderInfo.getId() , orderInfo.getUserId()) , 30 , TimeUnit.SECONDS) ;
        Map<String  , String> map = new HashMap<>() ;
        map.put("orderId" , String.valueOf(orderInfo.getId())) ;
        map.put("userId" , String.valueOf(orderInfo.getUserId())) ;
        rabbitTemplate.convertAndSend("order.exchange" , "order.info" , JSON.toJSONString(map));

        AbstractOrderHandler abstractOrderHandler = this.getNext();
        if(abstractOrderHandler != null) {
            return abstractOrderHandler.process(orderSubmitDto , tradeNo) ;
        }

        return String.valueOf(orderInfo.getId());
    }

    // 保存订单的状态的日志数据
    private void saveOrderStatusLog(OrderInfo orderInfo) {
        OrderStatusLog orderStatusLog = new OrderStatusLog() ;
        orderStatusLog.setUserId(orderInfo.getUserId());
        orderStatusLog.setOrderId(orderInfo.getId());
        orderStatusLog.setOrderStatus(orderInfo.getOrderStatus());
        orderStatusLog.setOperateTime(new Date());
        orderStatusLogMapper.insert(orderStatusLog) ;
    }

    // 保存订单明细数据
    private void saveOrderDetail(OrderInfo orderInfo, OrderSubmitDto orderSubmitDto) {

        List<DetailDto> orderDetailList = orderSubmitDto.getOrderDetailList();
        List<OrderDetail> detailList = orderDetailList.stream().map(detailDto -> {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setUserId(orderInfo.getUserId());
            orderDetail.setOrderId(orderInfo.getId());
            orderDetail.setSkuId(detailDto.getSkuId());
            orderDetail.setSkuName(detailDto.getSkuName());
            orderDetail.setImgUrl(detailDto.getImgUrl());
            orderDetail.setOrderPrice(detailDto.getOrderPrice());
            orderDetail.setSkuNum(String.valueOf(detailDto.getSkuNum()));
            orderDetail.setCreateTime(new Date());
            orderDetail.setSplitTotalAmount(detailDto.getOrderPrice().multiply(new BigDecimal(detailDto.getSkuNum())));
            orderDetail.setSplitActivityAmount(new BigDecimal("0"));
            orderDetail.setSplitCouponAmount(new BigDecimal("0"));
            return orderDetail;
        }).collect(Collectors.toList());
        orderDetailService.saveBatch(detailList) ;

    }

    // 保存订单数据
    private OrderInfo saveOrderInfo(OrderSubmitDto orderSubmitDto, String tradeNo) {

        // 创建OrderInfo对象
        OrderInfo orderInfo = new OrderInfo() ;
        orderInfo.setConsignee(orderSubmitDto.getConsignee());
        orderInfo.setConsigneeTel(orderSubmitDto.getConsigneeTel());

        // 计算总金额
        List<DetailDto> orderDetailList = orderSubmitDto.getOrderDetailList();
        BigDecimal totalAmount = orderDetailList.stream().map(detailDto -> detailDto.getOrderPrice().multiply(new BigDecimal(detailDto.getSkuNum())))
                .reduce((o1, o2) -> o1.add(o2)).get();
        orderInfo.setTotalAmount(totalAmount);
        orderInfo.setOrderStatus(OrderStatus.UNPAID.name());

        // 获取当前登录用户
        UserAuthInfo userAuthInfo = UserAuthUtils.getUserAuthInfo();
        String userId = userAuthInfo.getUserId();
        orderInfo.setUserId(Long.parseLong(userId));
        orderInfo.setPaymentWay(orderSubmitDto.getPaymentWay());
        orderInfo.setDeliveryAddress(orderSubmitDto.getDeliveryAddress());
        orderInfo.setOrderComment(orderSubmitDto.getOrderComment());
        orderInfo.setOutTradeNo(tradeNo);       // 唯一
        DetailDto detailDto = orderDetailList.get(0);
        orderInfo.setTradeBody(detailDto.getSkuName());
        orderInfo.setCreateTime(new Date());
        Long timeout = System.currentTimeMillis() +  1000 * 60 * 30 ;
        orderInfo.setExpireTime(new Date(timeout));
        orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());
        orderInfo.setTrackingNo("");        // 物流单号
        orderInfo.setParentOrderId(0L);     // 父订单的id
        orderInfo.setImgUrl(detailDto.getImgUrl());
        orderInfo.setProvinceId(0L);        // 省id
        orderInfo.setOperateTime(new Date());   // 操作时间
        orderInfo.setActivityReduceAmount(new BigDecimal("0"));     // 获取扣减金额
        orderInfo.setCouponAmount(new BigDecimal("0"));             // 优惠券的扣减金额
        orderInfo.setOriginalTotalAmount(totalAmount);
        orderInfo.setFeightFee(new BigDecimal("0"));                // 运费
        // orderInfo.setRefundableTime(new Date());                        // 可退款日期

        // 保存订单数据
        orderInfoMapper.insert(orderInfo) ;

        // 返回
        return orderInfo ;

    }
}
